package org.cytoscape.myapp.cytoscape_app_v1.internal;


import static org.cytoscape.work.ServiceProperties.ID;
import static org.cytoscape.work.ServiceProperties.MENU_GRAVITY;
import static org.cytoscape.work.ServiceProperties.PREFERRED_MENU;
import static org.cytoscape.work.ServiceProperties.TITLE;
import static org.cytoscape.work.ServiceProperties.ENABLE_FOR;


import java.util.Properties;

import org.cytoscape.application.CyApplicationManager;
import org.cytoscape.application.events.SetCurrentNetworkListener;
import org.cytoscape.application.swing.CyNodeViewContextMenuFactory;
import org.cytoscape.application.swing.CytoPanelComponent;
import org.cytoscape.event.CyEventHelper;
import org.cytoscape.group.CyGroupFactory;
import org.cytoscape.group.CyGroupManager;
import org.cytoscape.group.data.CyGroupAggregationManager;
import org.cytoscape.model.CyNetworkFactory;
import org.cytoscape.model.CyNetworkManager;
import org.cytoscape.model.subnetwork.CyRootNetworkManager;
import org.cytoscape.myapp.cytoscape_app_v1.internal.UI.CytoPanel;
import org.cytoscape.myapp.cytoscape_app_v1.internal.UI.RightClickMenu;
import org.cytoscape.myapp.cytoscape_app_v1.internal.UI.ViewUtilListener;
import org.cytoscape.myapp.cytoscape_app_v1.internal.layouts.CyLayoutsImpl;
import org.cytoscape.myapp.cytoscape_app_v1.internal.layouts.KKLayout.algorithms.KKNodeLayout;
import org.cytoscape.myapp.cytoscape_app_v1.internal.model.NetworkManager;
import org.cytoscape.myapp.cytoscape_app_v1.internal.model.UtilNetworkManager;
import org.cytoscape.myapp.cytoscape_app_v1.internal.tasks.CreateSubnetworkTask;
import org.cytoscape.myapp.cytoscape_app_v1.internal.tasks.groups.GroupsAggregationTask;
import org.cytoscape.myapp.cytoscape_app_v1.internal.visual.VisualInstanceDependecies;
import org.cytoscape.property.CyProperty;
import org.cytoscape.service.util.AbstractCyActivator;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.task.visualize.ApplyPreferredLayoutTaskFactory;
import org.cytoscape.view.layout.CyLayoutAlgorithm;
import org.cytoscape.view.layout.CyLayoutAlgorithmManager;
import org.cytoscape.view.model.CyNetworkViewFactory;
import org.cytoscape.view.model.CyNetworkViewManager;
import org.cytoscape.view.model.events.NetworkViewAddedListener;
import org.cytoscape.view.vizmap.VisualMappingFunctionFactory;
import org.cytoscape.view.vizmap.VisualMappingManager;
import org.cytoscape.view.vizmap.VisualStyleFactory;
import org.cytoscape.work.SynchronousTaskManager;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskManager;
import org.cytoscape.work.undo.UndoSupport;
import org.osgi.framework.BundleContext;

public class CyActivator extends AbstractCyActivator {

	@Override
	public void start(BundleContext context) throws Exception {
		
		
		CyApplicationManager applicationManager = getService(context, CyApplicationManager.class);
        
        // Access to all networks
        CyNetworkManager networkManager = getService(context, CyNetworkManager.class);
        
        CyNetworkFactory networkFactory = getService(context, CyNetworkFactory.class);
        
        
        // The CyGroupManager maintains information about all of the groups an instance of Cytoscape.
        CyGroupManager groupManager = getService(context, CyGroupManager.class);
        
        // An interface describing a factory used for creating CyGroup objects.
        CyGroupFactory groupFactory = getService(context, CyGroupFactory.class);
        
        CyNetworkViewManager networkViewManager = getService(context, CyNetworkViewManager.class);
        
        CyNetworkViewFactory networkViewFactory = getService(context, CyNetworkViewFactory.class);
		
        TaskManager taskManager = getService(context, TaskManager.class);
        
        //UnGroupNodesTaskFactory unGroupFactory = getService(context, UnGroupNodesTaskFactory.class);
        CyEventHelper eventHelper = getService(context, CyEventHelper.class);
        
        CyRootNetworkManager rootNetwork = getService(context,CyRootNetworkManager.class);
        
        CyLayoutAlgorithmManager layoutAlgorithmManager = getService(context, CyLayoutAlgorithmManager.class); 
       
        ApplyPreferredLayoutTaskFactory applyPreferredLayoutTaskFactory = getService(context, ApplyPreferredLayoutTaskFactory.class);
        
  
		ViewUtilListener viewDefaultListener = new ViewUtilListener(layoutAlgorithmManager, taskManager);
		registerService(context, viewDefaultListener, NetworkViewAddedListener.class, new Properties());
		
				    
	    CreateSubnetworkTask createSub = new CreateSubnetworkTask(applicationManager, groupManager, networkManager,
	    									networkViewManager, networkViewFactory, rootNetwork);
	    
	    Properties settingsProps = new Properties();
	    settingsProps.setProperty(ID,"RightClickMenu");
	    settingsProps.setProperty(PREFERRED_MENU,"SUB-RED");
	    settingsProps.setProperty(MENU_GRAVITY, "-1");
	    settingsProps.setProperty(TITLE, "GENERAR SUB-RED");
	    settingsProps.setProperty(ENABLE_FOR,"false");
	
	
		RightClickMenu click= new RightClickMenu(settingsProps,createSub,taskManager,groupManager);

		registerService(context,click,CyNodeViewContextMenuFactory.class, settingsProps);
		
		CyProperty cyPropertyServiceRef = getService(context,CyProperty.class,"(cyPropertyName=cytoscape3.props)");
		UndoSupport undoSupportServiceRef = getService(context,UndoSupport.class);
		CyServiceRegistrar cyServiceRegistrar = getService(context,CyServiceRegistrar.class);
		
		//GridNodeLayout gridNodeLayout = new GridNodeLayout(undoSupportServiceRef);
		//CyLayoutsImpl cyLayouts = new CyLayoutsImpl(cyServiceRegistrar, cyPropertyServiceRef, gridNodeLayout);
		KKNodeLayout kkNodeLayout = new KKNodeLayout(undoSupportServiceRef, applicationManager);
		CyLayoutsImpl cyLayouts = new CyLayoutsImpl(cyServiceRegistrar, cyPropertyServiceRef, kkNodeLayout);
		
		registerService(context,cyLayouts,CyLayoutAlgorithmManager.class, new Properties());

		Properties gridNodeLayoutProps = new Properties();
		gridNodeLayoutProps.setProperty(PREFERRED_MENU,"Layout.Cytoscape Layouts");
		gridNodeLayoutProps.setProperty("preferredTaskManager","menu");
		gridNodeLayoutProps.setProperty(TITLE,kkNodeLayout.toString());
		gridNodeLayoutProps.setProperty(MENU_GRAVITY,"10.0");
		registerService(context,kkNodeLayout,CyLayoutAlgorithm.class, gridNodeLayoutProps);

		registerServiceListener(context,cyLayouts,"addLayout","removeLayout",CyLayoutAlgorithm.class);
		
		
		
		VisualMappingManager vmmServiceRef = getService(context,VisualMappingManager.class);
		
		VisualStyleFactory visualStyleFactoryServiceRef = getService(context,VisualStyleFactory.class);
		
		VisualMappingFunctionFactory vmfFactoryC = getService(context,VisualMappingFunctionFactory.class, "(mapping.type=continuous)");
		VisualMappingFunctionFactory vmfFactoryD = getService(context,VisualMappingFunctionFactory.class, "(mapping.type=discrete)");
		VisualMappingFunctionFactory vmfFactoryP = getService(context,VisualMappingFunctionFactory.class, "(mapping.type=passthrough)");
		
		VisualInstanceDependecies visualInstanceDependecies = new VisualInstanceDependecies(vmmServiceRef, visualStyleFactoryServiceRef, vmfFactoryC, vmfFactoryD, vmfFactoryP, applicationManager);
		
		
		
//		CyGroupAggregationManager aggregationManager = getService(context, CyGroupAggregationManager.class);
//		
//		taskManager.execute(new TaskIterator(new GroupsAggregationTask(aggregationManager)));
		
		UtilNetworkManager utilNetworkManager = new NetworkManager(applicationManager, groupManager, groupFactory, visualInstanceDependecies, kkNodeLayout);
		
		CytoPanel panel =  new CytoPanel(applicationManager,groupManager,taskManager, utilNetworkManager, eventHelper);

		//Registro los servicios con los observadores
		registerService(context, panel, CytoPanelComponent.class, new Properties());
		registerService(context, panel, SetCurrentNetworkListener.class, new Properties());
	}

}
